package com.explment.lens.service.token;

import com.explment.lens.exception.BusinessException;
import com.explment.lens.service.redis.RedisService;
import com.explment.lens.utils.jwt.JwtTokenProvider;
import com.explment.lens.utils.result.ResultCode;
import com.explment.lens.utils.result.ResultData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

@Service
public class TokenRefreshService {
    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @Autowired
    private RedisService redisService;

    /**
     * 刷新令牌的方法
     *
     * @param refreshToken 刷新令牌
     * @return 包含新访问令牌和新刷新令牌的Map
     * @throws RuntimeException 如果刷新令牌无效或不匹配，抛出运行时异常
     */
    public Map refreshTokens(String refreshToken) {
        Map map = new HashMap();
        if (!jwtTokenProvider.validateToken(refreshToken)) {
            throw new BusinessException(ResultCode.BAD_REQUEST,"Refresh token invalid");
        }

        String username = jwtTokenProvider.getUsernameFromToken(refreshToken);
        String storedToken = (String) redisService.get("refresh:" + username);

        if (!refreshToken.equals(storedToken)) {
            throw new BusinessException(ResultCode.BAD_REQUEST,"Refresh token mismatch");
        }

        String newAccessToken = jwtTokenProvider.generateAccessToken(username);
        String newRefreshToken = jwtTokenProvider.generateRefreshToken(username);

        // 刷新令牌轮转（旧Refresh Token立即失效）
        redisService.delete("refresh:" + username);
        redisService.set("refresh:" + username,newRefreshToken,jwtTokenProvider.getRefreshExpiration());

        map.put("accessToken", newAccessToken);
        map.put("refreshToken", newRefreshToken);
        return map;
    }

    /**
     * 注销用户的方法
     *
     * @param refreshToken 刷新令牌
     * @return 包含状态信息的Map
     */
    public ResultData logout(String refreshToken) {
        redisService.delete("access:" + jwtTokenProvider.getUsernameFromToken(refreshToken));
        redisService.delete("refresh:" + jwtTokenProvider.getUsernameFromToken(refreshToken));
        SecurityContextHolder.clearContext();
        return ResultData.success(ResultCode.SUCCESS);
    }
}